使用了这么久Vue,一直没去了解Vue的双向绑定原理,正好最近做项目遇到了数据更新的问题,就顺便了解了下Vue的数据响应机制
我遇到的问题是在data中定义一个对象 –> btnControl,并在收到ajax数据时给btnControl动态添加属性,使用btnControl中的属性来控制div的隐藏与显示
当我改变btnControl中某个属性的值为True(为了让当前input显示出来) 的时候,浏览器的input并没有显示出来,在控制台输出的值的确是已经改变了!!!
在这边无论怎么点都没有响应
我想要这样的效果
是什么原因导致页面没有及时更新呢? 为什么vue没有监听到数据的变化而重新渲染页面呢? 问题就在这!!!
因为我的btnControl对象中的属性是动态添加的,没有在data中事先定义好,所以当属性改变时无法被vue监听到,做出响应(重新渲染视图)
官网也给出了解决方案
然后我修改了代码,实现了v-if的显示与隐藏.
那么Vue是通过什么来监听data中的数据改变呢?Vue是如何实现数据双向绑定的呢?
Object.defineProperty
使用Object.defineProperty监听对象a的 ‘name’属性,当写入,读取时就会自动触发get/set!
我们来测试一下给a的name写入和读取
- 写入(set)
- 这里触发了set中的console.log,并且也给input绑定上值了
读取(get)
因为我没有在data中事先定义btnControl的属性,所以vue无法侦听btnControl属性的变化–>所以不能更新视图
那我使用的$set的原理是什么呢?我觉得是给指定对象添加了属性的监听,我决定去看下源码!
总结
1. 想要vue的视图及时更新,就需要一开始在data中定义好,那么vue组件渲染时,就会给所有挂载在data中的对象深度遍历,对每个对象/属性进行监听!
2. 如果需要动态添加data中对象的属性,可以使用$set来添加–>原理就是手动指定Object.defineProperty的监听对象,从而触发vue的数据驱动视图更新!